<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:nyext="urn:noury-extensions">
  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:param name="assembly" />
  <xsl:param name="id" />
  <xsl:param name="outdir" />

  <xsl:include href="functions.xslt" />

	<msxsl:script language="C#" implements-prefix="nyext">
		<![CDATA[
      public static string getPublicKey(string path) {
        using (
          System.IO.BinaryWriter bw=new System.IO.BinaryWriter(
            new System.IO.MemoryStream()
          )
        )
          using (
            System.IO.BinaryReader br=new System.IO.BinaryReader(
              System.IO.File.OpenRead(path)
            )
          )
          {
            br.BaseStream.Position=0;
    
            // Read BLOBHEADER
            byte keyType=br.ReadByte();
            byte blobVersion=br.ReadByte();
            UInt16 reserverd=br.ReadUInt16();
            UInt32 algorithmID=br.ReadUInt32();
    
            // Read RSAPUBKEY
            string magic=new string(br.ReadChars(4));
            UInt32 keyBitLength=br.ReadUInt32();
            UInt32 rsaPublicExponent=br.ReadUInt32();
    
            // Read Modulus
            byte[] rsaModulus=br.ReadBytes((int)(keyBitLength/8));
            br.Close();
  
            bw.Write((UInt32)0x00002400);
            bw.Write((UInt32)0x00008004);
            bw.Write(rsaModulus.Length+20);
            bw.Write((byte)0x06);
            bw.Write((byte)0x02);
            bw.Write((UInt16)0x0000);
            bw.Write((UInt32)0x2400);
            bw.Write("RSA1".ToCharArray());
            bw.Write(keyBitLength);
            bw.Write(rsaPublicExponent);
            bw.Write(rsaModulus);
  
            System.Text.StringBuilder sb=new System.Text.StringBuilder();
            foreach (byte b in ((System.IO.MemoryStream)bw.BaseStream).ToArray())
              sb.AppendFormat("{0:X2}", b);
  
            bw.Close();
  
            return sb.ToString();
        }
      }
		]]>
	</msxsl:script>
  
  <xsl:template name="generate-user-file">
    <xsl:text>// $Id$
/*! \file
 * \brief Assembly information.
 *
 * \author $Author$
 * \date $Date$
 * \version $Revision$
 */

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("</xsl:text>
    <xsl:value-of select="$assembly" />
    <xsl:text>")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("</xsl:text>
    <xsl:value-of select="$id" />
    <xsl:text>")]

</xsl:text>
    <xsl:for-each select="/manifest/solution//project[@id=concat('{', $id , '}')]//internal">
      <xsl:variable name="pn" select="@name" />
      <xsl:variable name="p" select="/manifest/solution//project[@name=$pn]" />
      
      <xsl:if test="$p">
        <xsl:text>[assembly:InternalsVisibleTo("</xsl:text>
        <xsl:value-of select="$p/@assembly" />
        <xsl:text>, PublicKey=</xsl:text>
        <xsl:value-of select="nyext:getPublicKey('bin/src/misc/Project.snk')" />
        <xsl:text>")]
</xsl:text>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="/">
    <xsl:call-template name="generate-user-file" />
  </xsl:template>
</xsl:stylesheet>
